package org.dev.`as`.project.common.flutter

import android.content.Context
import android.os.Handler
import android.os.Looper
import android.os.MessageQueue
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.engine.FlutterEngineCache
import io.flutter.embedding.engine.FlutterJNI
import io.flutter.embedding.engine.dart.DartExecutor
import io.flutter.embedding.engine.loader.FlutterLoader
import io.flutter.view.FlutterMain
import org.dev.`as`.project.common.flutter.view.HiImageViewPlugin
import org.dev.hi.library.log.HiLog
import org.dev.hi.library.util.HiFileUtil


/**
 * Flutter优化提升加载速度，实现秒开Flutter模块
 * 0.如何让预加载不损失"首页"性能
 * 1.如何实例化多个Flutter引擎并分别加载不同的dart 入口文件
 */
class HiFlutterCacheManager private constructor() {


    companion object {
        // 收藏页对应的时main.dart中main方法对应的页面
        const val MODULE_NAME_FAVORITE = "main"
        // 推荐页对应的是recommend对应的页面
        const val MODULE_NAME_RECOMMEND = "recommend"

        @JvmStatic
        @get:Synchronized
        var instance: HiFlutterCacheManager? = null
            get() {
                if (field == null) {
                    field = HiFlutterCacheManager()
                }
                return field
            }
            private set
    }

    /**
     * 预加载FlutterEngine
     */
    fun preLoad(
        context: Context) {
        // 线程空闲的时候进行预加载
        Looper.myQueue().addIdleHandler {
            initFlutterEngine(context, MODULE_NAME_FAVORITE)
            initFlutterEngine(context, MODULE_NAME_FAVORITE)
            false
        }

/*        val messageQueue = Looper.myQueue()
        HiFileUtil.copyAssetsFile2FilesDir(context, HiFlutterLoader.FIX_SO, listener = {
            //在线程空闲时执行预加载任务
            messageQueue.addIdleHandler {
                initFlutterEngine(context, MODULE_NAME_FAVORITE)
                initFlutterEngine(context, MODULE_NAME_RECOMMEND)
                false
            }
        })*/
    }

    /**
     * 获取预加载的FlutterEngine
     */
    fun getCachedFlutterEngine(moduleName: String, context: Context?): FlutterEngine? {
        var engine = FlutterEngineCache.getInstance()[moduleName]
        if (engine == null && context != null) {
            engine = initFlutterEngine(context, moduleName)
        }
        return engine!!
    }

    fun hastCached(moduleName: String): Boolean {
        return FlutterEngineCache.getInstance().contains(moduleName)
    }

    /**
     * 销毁FlutterEngine
     */
    fun destroyCached(moduleName: String) {
        FlutterEngineCache.getInstance()[moduleName]?.apply {
            destroy()
        }
        FlutterEngineCache.getInstance().remove(moduleName)
    }

    /**
     * DartVM 预热
     */
    fun preLoadDartVM(context: Context) {
        val settings = FlutterLoader.Settings()
        FlutterLoader.getInstance().startInitialization(context, settings);
        val mainHandler = Handler(Looper.getMainLooper())
        FlutterLoader.getInstance().ensureInitializationCompleteAsync(
            context, arrayOf(),
            mainHandler
        ) {
            HiLog.i("Flutter preLoadDartVM done")
        }

    }

    /**
     * 初始化FlutterEngine
     */
    private fun initFlutterEngine(
        context: Context,
        moduleName: String
    ): FlutterEngine {
        // 创建一个flutterEngine
        val flutterEngine = FlutterEngine(context)
        // 插件注册要紧跟引擎初始化后,否则会有时序问题
        HiFlutterBridge.init(flutterEngine)
        flutterEngine.dartExecutor
            .executeDartEntrypoint(
                DartExecutor.DartEntrypoint(
                    FlutterMain.findAppBundlePath(), moduleName
                )
            )
        // 设置缓存
        FlutterEngineCache.getInstance()
            .put(moduleName, flutterEngine)
        return flutterEngine
    }

}